package pub.devrel.easypermissions.helper;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.fraction.Fraction;
import ohos.app.AbilityContext;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.util.List;

/**
 * Delegate class to make permission calls based on the 'host' (Fragment, Ability, etc).
 */
public abstract class PermissionHelper<T> {
    private static final HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");
    private T mHost;

    public static PermissionHelper<? extends Ability> newInstance(Ability host) {
        if (host instanceof Ability) {
            return new AppCompatAbilityPermissionsHelper(host);
        } else {
            return new AbilityPermissionHelper(host);
        }
    }

    public static PermissionHelper<Fraction> newInstance(Fraction host) {
        return new SupportFragmentPermissionHelper(host);
    }

    // ============================================================================
    // Public concrete methods
    // ============================================================================

    public PermissionHelper(T host) {
        mHost = host;
    }

    private boolean shouldShowRationale(String... perms) {
        for (String perm : perms) {
            HiLog.info(TAG, "shouldShowRationale perm = " + perm);
            if (shouldShowRequestPermissionRationale(perm)) {
                return true;
            }
        }
        return false;
    }

    public void requestPermissions(String rationale,
                                   String positiveButton,
                                   String negativeButton,
                                   int theme,
                                   int requestCode,
                                   String... perms) {
        HiLog.info(TAG, "shouldShowRationale = " + shouldShowRationale(perms));
        if (shouldShowRationale(perms)) {
            showRequestPermissionRationale(
                rationale, positiveButton, negativeButton, theme, requestCode, perms);
        } else {
            directRequestPermissions(requestCode, perms);
        }
    }

    public boolean somePermissionPermanentlyDenied(List<String> perms) {
        for (String deniedPermission : perms) {
            if (permissionPermanentlyDenied(deniedPermission)) {
                return true;
            }
        }

        return false;
    }

    public boolean permissionPermanentlyDenied(String perms) {
        return !shouldShowRequestPermissionRationale(perms);
    }

    public boolean somePermissionDenied(String... perms) {
        return shouldShowRationale(perms);
    }

    public T getHost() {
        return mHost;
    }

    // ============================================================================
    // Public abstract methods
    // ============================================================================

    public abstract void directRequestPermissions(int requestCode, String... perms);

    public abstract boolean shouldShowRequestPermissionRationale(String perm);

    public abstract void showRequestPermissionRationale(String rationale,
                                                        String positiveButton,
                                                        String negativeButton,
                                                        int theme,
                                                        int requestCode,
                                                        String... perms);

    public abstract AbilityContext getContext();
}
